package server;

import java.io.*;
import java.net.*;
import java.util.Observable;

import protocol.ClientProtocol;
import protocol.ServerProtocol;

/**
 * P2 prac wk4.
 * ClientHandler. Een klasse voor het onderhouden van een 
 * socketverbinding tussen een Client en een Server.
 * @author  Tim en Stef
 */
public class ClientHandler extends Observable implements Runnable {

	
	public static final int EXIT = -1;
    private Socket           sock;
    private BufferedReader   in;
    private BufferedWriter   out;
    private String 			 name;

    /**
     * Construeert een ClientHandler object.
     * Initialiseert de beide Data streams.
     * @require sock != null
     */
    public ClientHandler(Socket sock) throws IOException {
        this.sock = sock;
        
        in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        out= new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
    }
    /**
     * Vangt berichten op uit de socket verbinding en stuurt deze door naar de observers
     */
    public void run() {
    	while(!sock.isClosed()){
        	String t=null;
			try {
				t = in.readLine();
			} catch (IOException e) {
				shutdown();
			}
        	if(t!=null){
        		setChanged();
        		this.notifyObservers(t);
        	}else{
        		this.shutdown();
        	}
        	
        	
        }
    }

    /**
     * Deze methode kan gebruikt worden om een bericht over de 
     * socketverbinding naar de Client te sturen. Als het schrijven
     * van het bericht mis gaat, dan concludeert de methode dat de
     * socketverbinding verbroken is en roept shutdown() aan.
     */
    public void sendMessage(String msg) {
    	try {
			out.write(msg+"\n");
			out.flush();
		} catch (IOException e) {
			shutdown();
		}
    }
    
    /**
     * Stuurt een commando naar de client.
     * @param command Het specifieke commando.
     * @param args De argumenten van het commando.
     */
    public void sendCommand(String command, String[] args){
    	String message = command;
    	if(args!=null)
    	for(String s:args){
    		message =message + ServerProtocol.DELIM + s;
    	}   
    	sendMessage(message);
    }

    /**
     * Sluit de verbinding en geeft door aan de Observers dat de verbinding gesloten word.
     */
    private void shutdown() {
		setChanged();
		this.notifyObservers(ClientHandler.EXIT);
        try {
			sock.close();
	        in.close();
	        out.close();
		} catch (IOException e) {
			
		}

    }
    /**
     * Veranderd de naam van de client
     * @param n De nieuwe naam
     */
    public void setName(String n){
    	name = n;
    }
    /**
     * @return de naam van de client
     */
    public String getName(){
    	return name;
    }

} // end of class ClientHandler
